<!--
 * @Author: 四川华西绿舍建材有限公司
 * @Date: 2023-11-18 10:25:19
 * @LastEditors: 陈波
 * @LastEditTime: 2024-04-25 17:05:41
 * @Description: 
 * @FilePath: \graDesign\src\views\User\Register\index.vue
-->
<template>
  <div 
    class="register-container flex_center" 
    v-loading="fullScreenLoading" 
    element-loading-text="拼命加载中..."
    element-loading-background="rgba(0, 0, 0, 0.8)"
  >
    <div class="form-box">
      <h3 class="form-title">新用户注册</h3>
      <el-form
        ref="ruleFormRef"
        :model="ruleForm"
        :rules="rules"
        label-width="120px"
        class="ruleFormStyle"
        status-icon
      >
        <el-form-item label="用户名" prop="username">
          <el-input v-model="ruleForm.username" clearable />
        </el-form-item>
        <el-form-item label="密码" prop="password">
          <el-input
            type="password"
            show-password
            clearable
            v-model="ruleForm.password"
          />
        </el-form-item>
        <el-form-item label="确认密码" prop="ensurePassword">
          <el-input
            type="password"
            show-password
            clearable
            v-model="ruleForm.ensurePassword"
          />
        </el-form-item>
        <el-form-item label="人脸数据" class="login-mid-mid" prop="faceBase">
          <FaceEnter @confirm="confirmFace" :clearFaceBase="clearFaceBase" />
        </el-form-item>
        <el-form-item label="手机号" prop="phone">
          <div class="phone-container flex_between">
            <el-input v-model="ruleForm.phone" clearable />
            <!-- <el-button
              type="primary"
              plain
              :disabled="isDisableCode"
              :loading="isLoading"
              @click="sendCode"
            >
              {{ sendCodeStatus ? `再次发送${isSecondes}` : "获取验证码" }}
            </el-button> -->
          </div>
        </el-form-item>
        <el-form-item prop="security" label="密保问题">
          <el-link 
            :underline="false"
            type="primary"
            @click="dialogVisible = true"
            v-if="!isSetSecurity"
          >
            点击设置密保问题以方便找回密码
          </el-link>
          <el-tag 
            type="success" 
            size="large"
            @click="dialogVisible = true"
            v-else
          >
            <div class="pointer flex_center">
              <el-icon><CircleCheck /></el-icon>
              <span>已设置密保问题</span>
            </div>
          </el-tag>
        </el-form-item>

        <el-form-item label="选择头像">
          <!-- <el-link 
            :underline="false"
            type="primary"
            @click="fileDialogVisible = true"
          >
            点击选择头像
          </el-link> -->
          <el-upload
            v-model:file-list="fileList"
            action="#"
            list-type="picture-card"
            :auto-upload="false"
            :limit="1"
            :on-remove="handleRemove"
            :on-preview="handlePictureCardPreview"
          >
            <el-icon><Plus /></el-icon>
          </el-upload>

          <!-- <el-upload
            class="avatar-uploader"
            action="/api/tbuser/upload-image"
            :show-file-list="false"
            :on-success="handleAvatarSuccess"
            :before-upload="beforeAvatarUpload"
          >
            <img v-if="imageUrl" :src="imageUrl" class="avatar" />
            <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
          </el-upload> -->
        </el-form-item>

        <el-form-item>
          <el-button type="success" @click="submitForm(ruleFormRef)">
            注册
          </el-button>
          <el-button @click="resetForm(ruleFormRef)">重置</el-button>
        </el-form-item>
      </el-form>
    </div>
  </div>
  <!-- 密保问题弹出框 -->
  <BasicDialog
    :visible="dialogVisible"
    width="35%"
    :showClose="true"
    @handleClose="close"
    :hasHeadDivider="true"
  >
    <template #header>
      <span slot="header">请设置密保问题~</span>
    </template>
    <el-form
      ref="sRuleFormRef"
      :model="sForm"
      :rules="sFormRules"
      status-icon
      style="margin-top: -50px;"
    > 
      <el-row :gutter="20">
        <el-col :span="13">
          <el-form-item label="问题一：" prop="question1">
            <el-select
              v-model="sForm.question1"
              placeholder="请选择"
            >
              <el-option
                v-for="item in options1"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="11">
          <el-form-item label="答案：" prop="answer1">
            <el-input v-model="sForm.answer1" placeholder="Please input" />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="20">
        <el-col :span="13">
          <el-form-item label="问题二：" prop="question2">
            <el-select
              v-model="sForm.question2"
              placeholder="请选择"
            >
              <el-option
                v-for="item in options2"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="11">
          <el-form-item label="答案：" prop="answer2">
            <el-input v-model="sForm.answer2" placeholder="Please input" />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="20">
        <el-col :span="13">
          <el-form-item label="问题三：" prop="question3">
            <el-select
              v-model="sForm.question3"
              placeholder="请选择"
            >
              <el-option
                v-for="item in options3"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="11">
          <el-form-item label="答案：" prop="answer3">
            <el-input v-model="sForm.answer3" placeholder="Please input" />
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <template #footer>
      <span slot="footer" class="dialog-footer">
        <el-button @click="close" v-show="!isSetSecurity">取 消</el-button>
        <el-button type="success" @click="saveSecurity(sRuleFormRef)">确 定</el-button>
      </span>
    </template>
  </BasicDialog>
  <!-- 头像选择弹出框 -->
  <!-- <fileAvatar
    :fileDialogVisible="fileDialogVisible"
    @close="closeFileDialog"
  /> -->
  <!-- 头像查看 -->
  <el-dialog 
    v-model="fileDialogVisible"
    width="50%"
  >
    <img 
      :src="dialogImageUrl" 
      alt="Preview Image"
      style="width: 100%; height: 100%;"
    />
  </el-dialog>
</template>

<script setup lang="ts">
import { reactive, ref, watch } from 'vue';
import type { FormInstance, FormRules } from "element-plus";
// class
import { RuleForm, Register } from "@/types/Register/registerClass";
// utils
import { checkPassword, checkPhone } from "@/utils/util";
// 消息弹出框
import { showMessageBox, showNotification } from "@/utils/alertMsg";
import { options1, options2, options3 } from './options'
// import { Star } from "@element-plus/icons-vue";
// api
import registerApi from "@/request/api/register";
import { Delete, Download, Plus, ZoomIn } from '@element-plus/icons-vue'
import type { UploadFile } from 'element-plus'
// =========================================
import { useRouter } from 'vue-router';
import type { UploadProps, UploadUserFile  } from 'element-plus'

const router = useRouter();
const ruleFormRef = ref<FormInstance>();
const ruleForm = reactive<RuleForm>(new Register('', '', '', '', '', '', ''));

// 传递给后端的参数
const faceObj = reactive({
  fid: null,
  faceName: "",
  faceBase: "",
  faceStatus: 0,
  remark: "",
  addAndUpdateState: false,
});

// 获取验证码是否禁用？
let isDisableCode = ref<boolean>(true);

// 录入人脸回调
const confirmFace = (model: any) => {
  // 参数赋值
  faceObj.faceBase = model.faceBase;
  // 表单赋值
  ruleForm.faceBase = model.faceBase;
  clearFaceBase.value = false;
};

// 自定义校验
const validatePass = (rule: any, value: any, callback: any) => {
  if (value === "") {
    callback(new Error("请输入密码"));
  } else {
    if (ruleForm.ensurePassword !== "") {
      if (!ruleFormRef.value) return;
      ruleFormRef.value.validateField("checkPass", () => null);
    }
    // 校验密码
    if (!checkPassword(value)) {
      callback(
        new Error("密码格式错误，密码由数字、字母以及特殊字符组成且长度最少5位")
      );
    }
    callback();
  }
};
const validatePass2 = (rule: any, value: any, callback: any) => {
  if (value === "") {
    callback(new Error("请再次输入密码"));
  } else if (value !== ruleForm.password) {
    callback(new Error("两次密码不一致"));
  } else {
    callback();
  }
};

const validPhone = (rule: any, value: any, callback: any) => {
  if (value === "") {
    isDisableCode.value = true;
    callback(new Error("请输入您的手机号"));
  } else if (!checkPhone(value)) {
    isDisableCode.value = true;
    callback(new Error("手机号格式错误"));
  } else {
    isDisableCode.value = false;
    callback();
  }
};

// 校验规则
const rules = reactive<FormRules<RuleForm>>({
  username: [
    { required: true, message: "请输入您的用户名", trigger: "blur" },
    { min: 3, max: 15, message: "长度必须在3-15个字符之间", trigger: "blur" },
  ],
  password: [{ validator: validatePass, required: true, trigger: "blur" }],
  ensurePassword: [
    { validator: validatePass2, required: true, trigger: "blur" },
  ],
  faceBase: [{ required: true, message: "你必须录入人脸数据" }],
  phone: [{ validator: validPhone, required: true, trigger: "blur" }],
  security: [{ required: true, message: "请输入您的密保问题", trigger: "blur" }]
});

// 是否清除已拍照的图片
const clearFaceBase = ref<boolean>(false);
// 重置
const resetForm = (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  clearFaceBase.value = true;
  // 清除表单同时 清除图片
  if (clearFaceBase.value) {
    ruleForm.faceBase = "";
  }
  for(let key in sForm) {
    sForm[key] = '';
  }
  isSetSecurity.value = false;
  formEl.resetFields();
};

/** 
  // 发送验证码的状态：false:未发送 true:已发送
  let sendCodeStatus = ref<boolean>(false);
  let sendCodeTime = ref<number>(30);
  let isLoading = ref<boolean>(false);
  // 计时器
  let timer = ref(null);
  // 发送验证码
  const sendCode = () => {
    sendCodeStatus.value = true;
    isLoading.value = true;
    sendCodeTime.value = 30;
    timer.value = setInterval(() => {
      sendCodeTime.value--;
      if (sendCodeTime.value === 0) {
        clearInterval(timer.value);
        // sendCodeStatus.value = false;
        isLoading.value = false;    
      }
    }, 1000);
    showMessageBox("success",  "验证码已发送");
  };

  // 0s就返回空
  const isSecondes = computed(() => {
    return sendCodeTime.value === 0 ? "" : `(${sendCodeTime.value}s)`;
  });
*/

interface ISForm {
  question1: string
  answer1: string
  question2: string
  answer2: string
  question3: string
  answer3: string
}
// 有没有设置密保问题
let isSetSecurity = ref<boolean>(false);
// 选择密保问题对话框
let dialogVisible = ref<boolean>(false);
const sRuleFormRef = ref<FormInstance>();
let sForm = reactive<ISForm>({
  question1: '',
  answer1: '',
  question2: '',
  answer2: '',
  question3: '',
  answer3: ''
});
const sFormRules = reactive<FormRules<ISForm>>({
  question1: [{ required: true, message: "请选择问题" }],
  answer1: [{ required: true, message: "请输入答案" }],
  question2: [{ required: true, message: "请选择问题" }],
  answer2: [{ required: true, message: "请输入答案" }],
  question3: [{ required: true, message: "请选择问题" }],
  answer3: [{ required: true, message: "请输入答案" }]
});

// 关闭对话框
const close = () => {
  dialogVisible.value = false;
};
// 重构sForm的数据并且存入ruleForm.security中
const formatSecurityToArrayString = (modelForm: ISForm): string => {
  const formattedArray = [];

  for (let i = 1; i <= Object.keys(modelForm).length / 2; i++) {
    const questionKey = 'question' + i;
    const answerKey = 'answer' + i;

    const question = modelForm[questionKey];
    const answer = modelForm[answerKey];

    const formattedObj = {};
    formattedObj[questionKey] = question;
    formattedObj[answerKey] = answer;

    formattedArray.push(formattedObj);
  }

  return JSON.stringify(formattedArray);

}

// 保存密保问题
const saveSecurity = (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  formEl.validate((valid, fields) => {
    if (valid) {
      ruleForm.security = formatSecurityToArrayString(sForm)
      isSetSecurity.value = true;
      showMessageBox("success", "保存成功");
      dialogVisible.value = false;
    } else {
      showNotification("error", "提示", "保存失败");
    }
  });
};

// // 头像文件上传
// let fileDialogVisible = ref<boolean>(false)

// // 关闭头像文件上传对话框
// const closeFileDialog = () => {
//   fileDialogVisible.value = false;
// }

const fileList = ref<UploadUserFile[]>([])
const dialogImageUrl = ref<string>('')
const fileDialogVisible = ref<boolean>(false)

// 读取图像 获取源数据
function readImage(file: File) {
  const reader = new FileReader();
  let imageBinaryData: string | ArrayBuffer;
  reader.onload = function(e) {
    // 如果你需要获取原始图片的二进制数据，可以使用 reader.result
    imageBinaryData = reader.result;
    ruleForm.avatar = imageBinaryData;
  };
  
  reader.readAsDataURL(file);
  // console.log('res', res)
}

const handleRemove = (file: UploadFile) => {
  fileList.value.pop();
}

watch(() => fileList.value, (newVal) => {
  // ruleForm.avatar = readImage(newVal[0].raw);
  if(Object.entries(newVal).length === 0) {
    ruleForm.avatar = ''
  } else {
    readImage(newVal[0].raw)
  }
}, { deep: true })

const handlePictureCardPreview = (file: UploadFile) => {
  dialogImageUrl.value = file.url!
  fileDialogVisible.value = true
}

// =============================================


// const imageUrl = ref('')

// const handleAvatarSuccess: UploadProps['onSuccess'] = (
//   response,
//   uploadFile
// ) => {
//   imageUrl.value = URL.createObjectURL(uploadFile.raw!)
// }

// const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
//   if (rawFile.type !== 'image/jpeg') {
//     ElMessage.error('Avatar picture must be JPG format!')
//     return false
//   } else if (rawFile.size / 1024 / 1024 > 2) {
//     ElMessage.error('Avatar picture size can not exceed 2MB!')
//     return false
//   }
//   return true
// }

let fullScreenLoading = ref<boolean>(false)
// 提交表单
const submitForm = async (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  await formEl.validate((valid, fields) => {
    if (valid) {
      fullScreenLoading.value = true;
      registerApi.useRegister(ruleForm).then((res: any) => {
        if(res.code == 500) {
          showMessageBox("error", res.msg);
        } else {
          showMessageBox("success", res.msg);
          router.push("/login")
        }
      }).finally(() => {
        fullScreenLoading.value = false;
      });
      // showMessageBox("success", "验证通过");
    } else {
      console.log("error submit!", fields);
      showNotification("error", "提示", "验证未通过");
    }
  });
};

// const eventNames = ['API_REQUEST_START', 'API_REQUEST_END'] as const;
// type EventNames = typeof eventNames[number];
</script>

<style scoped lang="scss">
.register-container {
  width: 100%;
  height: 100%;
  background: url("../../../assets/images/login/register-bg.png") no-repeat
    center;
  background-size: cover;
}

.form-box {
  width: 37%;
  padding: 10px;
  box-shadow:
    rgba(50, 50, 93, 0.25) 0px 50px 100px -20px,
    rgba(0, 0, 0, 0.3) 0px 30px 60px -30px,
    rgba(10, 37, 64, 0.35) 0px -2px 6px 0px inset;
  .form-title {
    text-align: center;
    margin: 20px 0;
  }
  .el-input {
    width: 97%;
  }
}

.el-form-item {
  margin: 20px 0;
}

.phone-container {
  // border: 1px solid red;
  width: 97%;
  .el-input {
    width: 100%;
  }
}

.avatar-uploader .avatar {
  width: 178px;
  height: 178px;
  display: block;
}
</style>

<style>
.avatar-uploader .el-upload {
  border: 1px dashed #9498a0;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: all 0.3s;
}

.avatar-uploader .el-upload:hover {
  border-color: #409eff;
}

.el-icon.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  text-align: center;
}
</style>
